package com.jeebey.mybatis.generic;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Options.FlushCachePolicy;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.session.RowBounds;

import com.jeebey.mybatis.query.Bounds;
import com.jeebey.mybatis.query.Criterion;
import com.jeebey.mybatis.query.Paging;

/**
 * @since 1.0
 * @author <a href="mailto:84961426@qq.com">JuST4iT</a>
 * @version $Id: GenericDao.java Feb 18, 2016 6:05:23 PM $
 */

public interface GenericDao<Entity, ID> {

	
	/**
	 * 全字段替换插入
	 * 仅mysql
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Insert("Generic.entity.replace.single")
	public Integer replaceEntity(Entity entity);
	
	/**
	 * 全字段插入
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Insert("Generic.entity.insert.single")
	public Integer insertEntity(Entity entity);

	/**
	 * 全字段插入
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Insert("Generic.entity.insert.notnul")
	public Integer insertEntitySelective(Entity entity);
	
	/**
	 * 全字段批量插入
	 * 
	 * @param entitys
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Insert("Generic.entity.insert.multiple")
	public Integer insertEntitys(List<Entity> entitys);

	/**
	 * 通过主键 全字段更新
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Update("Generic.entity.update.single")
	public Integer updateEntity(Entity entity);

	/**
	 * 通过主键 非空字段更新
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Update("Generic.entity.update.notnul")
	public Integer updateEntitySelective(Entity entity);

	
	/**
	 * 通过条件 字段更新
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Update("Generic.entity.update.single.criterion")
	public Integer updateEntityByCriterion(Entity entity,Criterion criterion);
	
	/**
	 * 通过条件 字段更新
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Update("Generic.entity.update.notnul.criterion")
	public Integer updateEntitySelectiveByCriterion(Entity entity,Criterion criterion);

	/**
	 * 通过主键 进行删除
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Delete("Generic.entity.delete.id")
	public Integer deleteEntityById(ID id);

	/**
	 * 通过主键 进行删除
	 * 
	 * @param entity
	 * @return
	 */
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Delete("Generic.entity.delete.ids")
	public Integer deleteEntityByIds(List<ID> ids);

	@Options(flushCache = FlushCachePolicy.TRUE)
	@Delete("Generic.entity.delete.condition")
	public Integer deleteEntitysByCriterion(Criterion criterion);
	
	/** 通过主键 进行 查询*/
	@Select("Generic.entity.select.id")
	public Entity selectEntityById(ID id);

	/** 无条件查询所有*/
	@Select("Generic.entity.select.all")
	public List<Entity> selectAllEntitys();
	
	@Select("Generic.entity.select.all.count")
	public Long selectAllCount();
	
	/** 通过主键 进行 查询*/
	@Select("Generic.entity.select.ids")
	public List<Entity> selectEntitysByIds(List<ID> ids);

	@Select("Generic.entity.select.condition.unique")
	public Entity selectEntityByCriterion(Criterion criterion);
	
	@Select("Generic.entity.select.condition.multiple")
	public List<Entity> selectEntitysByCriterion(Criterion criterion);

	@Select("Generic.entity.select.condition.count")
	public Long selectEntitysCountByCriterion(Criterion criterion);

	/** 逻辑分页*/
	@Select("Generic.entity.select.condition.rowbounds")
	public List<Entity> selectEntitysByCriterionRowBounds(Criterion criterion, RowBounds rowBounds);

	/** 是物理分页 依赖 net.lazytek.commons.mybatis.interceptor.PaginationInterceptor */
	@Select("Generic.entity.select.condition.bounds")
	public List<Entity> selectEntitysByCriterionBounds(Criterion criterion, Bounds bounds);
	
	/** 是物理分页 依赖 net.lazytek.commons.mybatis.interceptor.PaginationInterceptor 可强转 Pagination<Entity> */
	@Select("Generic.entity.select.condition.paging")
	public List<Entity> selectEntitysByPaging(Criterion condition, Paging<Entity> paging);

	
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Delete("Generic.custom.execute.delete.sql")
	public Integer executeCustomDeleteSQLBy(@Param("sql") String sql, @Param("list") List<?> params);
	
	@Select("Generic.custom.execute.select.sql")
	public <T>T executeCustomSelectObjSQLBy(@Param("sql") String sql, @Param("list") List<?> params, @Param("clazz") Class<T> clazz);
	
	@Select("Generic.custom.execute.select.sql")
	public <T>List<T> executeCustomSelectListSQLBy(@Param("sql") String sql, @Param("list") List<?> params, @Param("clazz") Class<T> clazz);

	@Options(flushCache = FlushCachePolicy.TRUE)
	@Update("Generic.custom.execute.update.sql")
	public Integer executeCustomUpdateSQLBy(@Param("sql") String sql, @Param("list") List<?> params);
	
	@Options(flushCache = FlushCachePolicy.TRUE)
	@Insert("Generic.custom.execute.insert.sql")
	public Integer executeCustomInsertSQLBy(@Param("sql") String sql, @Param("list") List<?> params);
	
	/** 通用层不可用,非通用层可用 */
	//@Select("Generic.entity.selects.condition.paging")
	//public Pagination<Entity> selectEntitysByPaging(Criterion condition, Paging<Entity> paging);

	/** 清除缓存*/
	@Select("Generic.entity.clear.cache")
	@Options(flushCache = FlushCachePolicy.TRUE)
	public int clearCache();
}
